﻿using System.Collections.Generic;
using Xamarin.Forms;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using static System.Math;
using static Moven.Statics;
using Moven.Views;
using Moven.Data;
using System;

namespace Moven.ViewModels
{
	public partial class ArticlesViewModel : BaseViewModel
    {
		const int PageSize = 15;

        readonly string _baseTitle;

		List<ArticleWithBookmark> _allArticles;

		public List<ArticleWithBookmark> AllArticles => _allArticles;

		List<ArticleWithBookmark> BaseArticles => IsSearchPage ? _searchResults : _allArticles;

		private MenuType MenuType { get; set; }

		public ListView ArticlesList { get; set; }

        public ArticlesViewModel(string title, 
		                         MenuType menuType,
		                         List<ArticleWithBookmark> articles)
        {
			MenuType = menuType;
            _baseTitle = title;
			articles = articles?? new List<ArticleWithBookmark>();
			LoadArticles(articles);
        }

		public void LoadArticles(List<ArticleWithBookmark> articles)
		{
			_allArticles = IsBookmarksPage ? new List<ArticleWithBookmark>() : articles;
			if (_articles == null)
			{
				_articles = IsSearchPage ? new ObservableCollection<ArticleWithBookmark>() :
					new ObservableCollection<ArticleWithBookmark>(
						IsBookmarksPage ? articles : articles.Take(PageSize));
			}
			else
			{
				foreach (var article in IsBookmarksPage ? articles : articles.Take(PageSize))
				{
					_articles.Add(article);
				}
			}
			HasMoreArticles = IsSearchPage ? false : PageSize < _allArticles.Count;
			InitSearch();
			UpdateTitle();
		}

		public void UpdateTitle()
		{
			if (IsSearchPage)
			{
				UpdateSearchTitle();
			}
			else
			{
				var selectionCount = Articles.Count(x => x.IsSelected);
				if (IsBookmarksPage && selectionCount > 0)
				{
					Title = $"已选择{selectionCount}篇";
				}
				else
				{
					var articleCount = Max(_allArticles.Count, Articles.Count);
					Title = _baseTitle + " [" + articleCount + "篇]";
				}
			}
		}

        private ObservableCollection<ArticleWithBookmark> _articles;
		public ObservableCollection<ArticleWithBookmark> Articles => _articles;

		public bool IsAllArticlesPage => MenuType == MenuType.AllArticles;

		public bool IsArticlesOfTagPage => MenuType == MenuType.ArticlesOfTag;

		public bool IsSearchPage => MenuType == MenuType.Search;

		public bool IsBookmarksPage => MenuType == MenuType.Bookmarks;

		public bool CanRefresh => IsAllArticlesPage || IsArticlesOfTagPage;

		public string Tag { get; set; }    // For tags page

        private ArticleWithBookmark _selectedArticle;
        /// <summary>
        /// Gets or sets the selected article
        /// </summary>
        public ArticleWithBookmark SelectedArticle
        {
            get { return _selectedArticle; }
            set
            {
                _selectedArticle = value;
				if (value == null)
				{
					return;
				}
                OnPropertyChanged();
				GotoArticleDetail(_selectedArticle);
            }
        }

        Command _refreshArticlesCommand;
        public Command RefreshArticlesCommand => _refreshArticlesCommand ?? 
                (_refreshArticlesCommand = new Command(async () => await RefreshArticles()));

		Command _loadMoreArticlesCommand;

		bool _hasMoreArticles = true;

		public bool HasMoreArticles
		{
			get { return _hasMoreArticles; }
			set { SetProperty(ref _hasMoreArticles, value); }
		}

		public Command LoadMoreArticlesCommand => _loadMoreArticlesCommand ??
		(_loadMoreArticlesCommand = new Command(_ => LoadMoreArticles(BaseArticles), _ => HasMoreArticles));

		void LoadMoreArticles(List<ArticleWithBookmark> allArticles)
		{
			var newArticles = allArticles.Skip(Articles.Count).Take(PageSize).ToList();
			if (!newArticles.Any())
			{
				HasMoreArticles = false;
				return;
			}
			newArticles.ForEach(Articles.Add);
		}

        async Task RefreshArticles()
        {
			IsBusy = true;
			ShowHUD("正在刷新文章列表, 请稍候...");
			var refreshes = await Statics.ArticlesStore.RefreshArticlesAsync(true);
            IsBusy = false;
			if (refreshes.Status == RefreshArticlesStatus.Failure)
			{
				ShowErrorHUDWithStatus("刷新墨文失败, 请检查网络连接, 稍后再试");
				return;
			}
			var addedArticles = refreshes.NewArticles;

			var message = string.Empty;
			if (IsArticlesOfTagPage)
			{
				var newArticlesCount = addedArticles.Count(x => x.Tags.Contains(Tag));
				if (newArticlesCount == 0)
				{
					message = $"没有刷到{Tag}相关新墨文";
				}
				else
				{
					message = $"刷到{newArticlesCount}篇{Tag}相关新墨文";
				}
			}
			else
			{
				if (addedArticles.IsNullOrEmpty())
				{
					message = "没有刷到新墨文";
				}
				else
				{
					message = "刷到" + addedArticles.Count() + "篇新墨文";
				}
			}

			ShowSuccessHUDWithStatus(message);
        }

		static readonly TimeSpan RippleAnimationDelay = TimeSpan.FromMilliseconds(200);
		public async Task GotoArticleDetail(ArticleWithBookmark article)
		{
			var detailPage = new ArticleDetailsView(article);
			if (IsIOS)
			{
				// Wait for the ripple animation to finish
				await Task.Delay(RippleAnimationDelay);
			}
			ArticlesList.SelectedItem = null;
			ArticleWithBookmark.UpdateBookmarksAsync(new[] { article });
			await Navigation.PushAsync(detailPage);
			article.IsNew = false;
		}
    }
}

